import { useState, useEffect } from 'react';
import { Form, Table, Row, Input, Pagination, Modal, Col } from 'antd';
import { axconst } from '@/shared/axconst';
import AxModal from '@/components/AxForm/AxModal/index';
import { AxEditableFormRow, AxEditableCellSimple, AxEditableContext } from '../AxFormItem';
import { AxColumnTime } from '@/components/AxList';
import styles from './style.less';
import InfiniteScroll from 'react-infinite-scroller';
import AxColumnAction from '@/components/AxList/AxColumnAction';
import AxTable from '@/components/AxList/AxTable';

const { Search } = Input;
/**
 * 证书冲抵
 * @param title 表单名称
 * @param placeholder 占位符
 * @param visible 可见性
 * @param handleVisible 可见性处理函数
 * @param handleRead 选项数据读取函数
 * @param handleCreate 添加处理函数
 */
const AxSelectCerOffset = props => {
  const {
    placeholder,
    offsetWaitData: offsetWaitDataFromProps,
    offsetedData: offsetedDataFromProps,
    handleRead: handleReadFromProps,
    handleCreate: handleCreateFromProps,
    handleVisible,
    ...rest
  } = props;
  /** 左侧待冲抵Table的引用 */
  const offsetWaitTableRef = React.createRef();
  /** 左侧待冲抵数据 */
  const [offsetWaitData, setOffsetWaitData] = useState({
    list: [],
    pagination: {},
  });
  /** 可冲抵的列表数据 */
  const [offsetListData, setOffsetListData] = useState({
    list: [],
    pagination: {},
  });
  /** 可冲抵的项目经费数据 */
  const [offsetDetailData, setOffsetDetailData] = useState({
    list: [],
    pagination: {},
  });
  /** 已冲抵数据 */
  const [offsetedData, setOffsetedData] = useState([]);
  /** 可冲抵的列表加载 */
  const [loading, setLoading] = useState(false);
  /** 收费项目经费编辑key */
  const [editingKey, setEditingKey] = useState(null);
  /** 收费项目经费编辑record */
  const [editingRecord, setEditingRecord] = useState(null);
  /** 选中的待冲抵行数据 */
  const [selectedWaitRows, setSelectedWaitRows] = useState([]);
  /** 查询字段 */
  let field = {};
  /** 分页初始值 */
  let page = axconst.page.params;

  useEffect(() => {
    setOffsetedData(offsetedDataFromProps || []);
  }, [offsetedDataFromProps]);
  useEffect(() => {
    setOffsetWaitData(offsetWaitDataFromProps);
  }, [offsetWaitDataFromProps]);

  /** 搜索 */
  const handleSearch = val => {
    if (val && val.trim() !== '') {
      field['name'] = val.trim();
    } else {
      field = {};
    }
    return handleRead();
  };

  /** 读取数据 */
  const handleRead = () => {
    if (handleReadFromProps) {
      setLoading(true);
      return handleReadFromProps(page, field).then(res => {
        setOffsetListData(res);
        setOffsetDetailData({ list: [], pagination: {} });
        setLoading(false);
      });
    }
  };
  /** 保存数据 */
  const handleCreate = () => {
    if (handleCreateFromProps)
      return handleCreateFromProps(offsetWaitData, offsetedData).then(res => {
        if (handleVisible) handleVisible();
      });
    return Promise.resolve();
  };

  /** 改变分页 */
  const handlePageChange = (currentPage, pageSize) => {
    page = {
      currentPage,
      pageSize,
    };
    handleRead();
  };

  /** 待冲抵的列表 */
  const columnsWait = [
    {
      title: '收费项目经费',
      dataIndex: 'itemName',
      sorter: false,
      // width: axconst.width.long,
      ellipsis: true,
    },
    {
      title: '应缴金额',
      dataIndex: 'shouldMoney',
      sorter: false,
      width: axconst.width.fouronly,
      ellipsis: true,
    },
    {
      title: '未冲金额',
      sorter: false,
      width: axconst.width.fouronly,
      ellipsis: true,
      render: (val, record) => {
        return (
          record.shouldMoney -
          (record.offsetMoney || 0) -
          (record.paidMoney || 0) -
          (record.discountMoney || 0)
        );
      },
    },
    {
      title: '已冲金额',
      dataIndex: 'offsetMoney',
      sorter: false,
      width: axconst.width.fouronly,
      ellipsis: true,
    },
    {
      title: '操作',
      fixed: 'right',
      width: axconst.width.four,
      render: (val, record) => (
        <AxColumnAction
          buttons={[
            {
              text: '清空冲抵',
              permissions: 2,
              group: false,
              onClick: e => clear(e, record),
            },
          ]}
        />
      ),
    },
  ];

  /** 可冲抵的列表 */
  let columnsList = [
    {
      title: '姓名',
      dataIndex: 'stuName',
      width: axconst.width.threeonly,
      ellipsis: true,
    },
    {
      title: '身份证',
      dataIndex: 'idCard',
      width: axconst.width.idcard,
      ellipsis: true,
    },
    {
      title: '证书名称',
      dataIndex: 'cerName',
      // width: axconst.width.fouronly,
      ellipsis: true,
      render: val => val || 0,
    },
    {
      title: '可冲金额',
      dataIndex: 'canMoney',
      width: axconst.width.fouronly,
      ellipsis: true,
    },
  ];

  /** 可冲抵的项目经费 */
  let columnsDetail = [
    {
      title: '收费项目经费',
      dataIndex: 'itemName',
      // width: axconst.width.fouronly,
      ellipsis: true,
    },
    {
      title: '可冲金额',
      dataIndex: 'canMoney',
      width: axconst.width.fouronly,
      ellipsis: true,
      render: (val, record) => {
        /** doMoney共计冲抵 */
        return val - (record.doMoney || 0);
      },
    },
    {
      title: '共计冲抵',
      dataIndex: 'doMoney',
      width: axconst.width.fouronly,
      ellipsis: true,
      render: val => val || 0,
    },
    {
      title: '本次冲抵',
      dataIndex: 'currentOffsetMoney',
      width: axconst.width.bill,
      ellipsis: true,
      editable: true,
      render: val => val || 0,
    },
  ];

  /** 选中待冲抵项 */
  const handleSelectOffsetWait = rows => {
    setSelectedWaitRows(rows);
    if (offsetWaitTableRef.current) handleCalculate(offsetedData, rows);
  };
  /** 获取收费项 */
  const handleSelectOffsetList = rows => {
    if (rows && rows.length === 1) {
      const d = { list: rows[0].feeDetails };
      setOffsetDetailData(d);
      handleCalculate(offsetedData, null, d);
    } else {
      setOffsetDetailData({ list: [] });
    }
  };
  /** 标记修改行 */
  const isEditing = record => record.id === editingKey;
  /** 取消 */
  const cancel = e => {
    if (e) e.stopPropagation();
    setEditingKey(null);
    setEditingRecord(null);
  };
  /** 修改 */
  const update = record => {
    setEditingKey(record.id);
    setEditingRecord(record);
  };
  /** 冲抵 */
  const calculateOffsetedData = (record, currentOffsetMoney) => {
    const wait = selectedWaitRows[0];
    const idx = offsetedData.findIndex(i => i.id === record.id && i.waitId === wait.id);
    /** 未冲抵金额 */
    const unOffsetMoney =
      wait.shouldMoney -
      (wait.offsetMoney || 0) -
      (wait.paidMoney || 0) -
      (wait.discountMoney || 0);
    if (idx > -1) {
      if (currentOffsetMoney > unOffsetMoney + (wait.offsetMoney || 0)) {
        Modal.error({
          title: '错误提示',
          content: '冲抵金额不能大于未冲抵金额',
        });
        return;
      }
      offsetedData[idx] = {
        waitId: wait.id,
        id: record.id,
        offsetMoney: currentOffsetMoney,
      };
    } else {
      if (currentOffsetMoney > unOffsetMoney) {
        Modal.error({
          title: '错误提示',
          content: '冲抵金额不能大于未冲抵金额',
        });
        return;
      }
      offsetedData.push({
        waitId: wait.id,
        id: record.id,
        offsetMoney: currentOffsetMoney,
      });
    }
    setOffsetedData(offsetedData);
    handleCalculate(offsetedData);
    setEditingKey(null);
    setEditingRecord(null);
  };
  /** 保存 */
  const save = (e, form, record) => {
    if (e) e.stopPropagation();

    form.validateFields((error, v) => {
      if (error) {
        return;
      }
      calculateOffsetedData(record, v.currentOffsetMoney);
    });
  };
  /** 清空冲抵 */
  const clear = (e, record) => {
    if (e) e.stopPropagation();
    const f = offsetedData.filter(i => i.waitId === record.id);
    f.forEach(i => {
      offsetedData.splice(offsetedData.indexOf(i), 1);
    });
    /** 清空 */
    setOffsetedData(offsetedData);
    /** 选中当前行 */
    if (offsetWaitTableRef.current) offsetWaitTableRef.current.handleSelectRow({ record });
  };
  /** 全部冲抵 */
  const saveAll = (e, record) => {
    if (e) e.stopPropagation();

    calculateOffsetedData(
      record,
      record.canMoney - (record.doMoney || 0) + (record.currentOffsetMoney || 0),
    );
  };
  /** 计算冲抵金额 */
  const handleCalculate = (offseted, waitSelectedRow, detailData) => {
    const waitId = waitSelectedRow ? waitSelectedRow[0].id : selectedWaitRows[0].id;
    detailData = detailData || offsetDetailData;
    /** 计算待冲抵数据 */
    setOffsetWaitData(old => {
      old.list.forEach(i => {
        let m = 0;
        offseted.forEach(j => {
          if (j.waitId === i.id) m += j.offsetMoney;
        });
        i.offsetMoney = m;
      });
      return { list: old.list };
    });
    /** 计算冲抵明细 */
    detailData.list.forEach(i => {
      /** 计算共计冲抵 */
      let m = 0;
      offseted.forEach(j => {
        if (j.id === i.id) m += j.offsetMoney;
      });
      i.doMoney = m;

      /** 获取本次冲抵 */
      const f = offseted.find(j => j.id === i.id && j.waitId === waitId);
      if (f) i.currentOffsetMoney = f.offsetMoney;
      else i.currentOffsetMoney = 0;
    });
    setOffsetDetailData({ list: detailData.list });
  };
  /** 单击修改 */
  const handleClick = record => {
    if (update) {
      update(record);
    }
  };
  /** 本次冲抵输入验证 */
  const validator = (rule, value, callback) => {
    rule.label = '';
    try {
      if (rule.required) {
        if (value === null || value === undefined || value === '') {
          throw new Error(`${rule.label}不能为空`);
        }
      }
      if (value && editingRecord) {
        if (parseFloat(value) > parseFloat(editingRecord.canMoney - (editingRecord.doMoney || 0))) {
          throw new Error(`${rule.label}不能大于可冲金额${rule.max}`);
        }
      }
      if (rule.pattern && rule.pattern.reg && value) {
        if (!new RegExp(rule.pattern.reg).test(value)) {
          if (rule.pattern.message) {
            throw new Error(rule.pattern.message);
          }
          throw new Error(`${rule.label}格式不正确`);
        }
      }
      callback(); // 通过验证
    } catch (err) {
      callback(err);
    }
  };
  columnsDetail = columnsDetail.map(col => {
    if (!col.editable) {
      return col;
    }
    return {
      ...col,
      onCell: record => ({
        record,
        editable: col.editable,
        required: true,
        enumName: col.enumName,
        dataIndex: col.dataIndex,
        title: col.title,
        cellType: col.cellType,
        data: col.data,
        pattern: col.pattern,
        // columnsNoChange: columnsNoChange,
        showValueWrap: true,
        cellType: 'number',
        validator: validator,
        editing: isEditing(record),
      }),
    };
  });
  columnsDetail.push({
    title: '操作',
    width: 80,
    render: (text, record) => {
      const editable = isEditing(record);
      const disabled = editingKey !== null;
      return editable ? (
        <span>
          <AxEditableContext.Consumer>
            {form => (
              <a onClick={e => save(e, form, record)} style={{ marginRight: 8 }}>
                冲抵
              </a>
            )}
          </AxEditableContext.Consumer>
          <a onClick={e => cancel(e)}>取消</a>
        </span>
      ) : (
        <AxColumnAction
          buttons={[
            {
              text: '全部冲抵',
              // icon: 'edit',
              onClick: e => saveAll(e, record),
            },
          ]}
        />
      );
    },
  });
  const components = {
    body: {
      row: AxEditableFormRow,
      cell: AxEditableCellSimple,
    },
  };

  return (
    <AxModal
      showLoading={false}
      width="50%"
      handleVisible={handleVisible}
      handleCreate={handleCreate}
      {...rest}
      items={[
        <Row gutter={12}>
          <Col span={12}>
            <div className={styles.demoInfiniteContainer}>
              <InfiniteScroll
                initialLoad={false}
                pageStart={0}
                loadMore={() => {}}
                useWindow={false}
              >
                <AxTable
                  selectFirstRecord
                  ref={offsetWaitTableRef}
                  columns={columnsWait}
                  data={offsetWaitData}
                  showPagination={false}
                  checkboxType="radio"
                  onSelectRow={handleSelectOffsetWait}
                />
              </InfiniteScroll>
            </div>
          </Col>
          <Col span={12}>
            <Row gutter={24}>
              <Search
                placeholder={placeholder ? placeholder : '搜索'}
                onSearch={val => handleSearch(val)}
                // style={{ width: '100%' }}
                allowClear
              />
              <AxTable
                columns={columnsList}
                data={offsetListData}
                loading={loading}
                showPagination={false}
                scroll={{ x: 'max-content', y: 173 }}
                checkboxType="radio"
                onSelectRow={handleSelectOffsetList}
              />
              <Pagination
                size="small"
                style={{ float: 'right', marginTop: '5px' }}
                pageSize={page.pageSize}
                total={offsetListData.pagination.total}
                onChange={handlePageChange}
              />
            </Row>
            ,
            <Row gutter={24}>
              <AxTable
                components={components}
                rowClassName={() => 'editable-row'}
                checkboxModel={false}
                columns={columnsDetail}
                data={offsetDetailData}
                showPagination={false}
                onRow={record => ({
                  onClick: () => {
                    if (handleClick) {
                      handleClick(record);
                    }
                  },
                })}
              />
            </Row>
            ,
          </Col>
        </Row>,
      ]}
    />
  );
};

export default Form.create()(AxSelectCerOffset);
